package com.taylor.community.quartz;

import com.taylor.community.entity.DiscussPost;
import com.taylor.community.service.DiscussPostService;
import com.taylor.community.service.ElasticsearchService;
import com.taylor.community.service.LikeService;
import com.taylor.community.util.CommunityConstant;
import com.taylor.community.util.RedisKeyUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 定时计算帖子分数的job(任务)
 */
public class PostScoreRefreshJob implements Job, CommunityConstant {
    private static final Logger logger = LoggerFactory.getLogger(PostScoreRefreshJob.class);
    private static final Date epoch;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DiscussPostService discussPostService;
    @Autowired
    private LikeService likeService;
    @Autowired
    private ElasticsearchService elasticsearchService;

    static {
        try {
            epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2014-08-01 00:00:00");
        } catch (ParseException e) {
            throw new RuntimeException("初始化牛客纪元失败！", e);
        }
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String redisKey = RedisKeyUtil.getPostScoreKey();
        //redisTemplate常用集合
        BoundSetOperations operations = redisTemplate.boundSetOps(redisKey);
        //倘若执行任务时，BoundSetOperations集合没有需要计算分数的帖子
        //因为每次计算分数要拿到帖子的id时通过pop()方法获取 所以集合可能出现没有帖子id的情况
        if(operations.size() == 0){
            logger.info("【任务取消】 没有需要刷新的帖子");
            return;
        }
        logger.info("【任务开始】 剩余需要刷新分数贴子数量为"+operations.size());
        while (operations.size()>0){
            this.refresh((Integer) operations.pop());
        }
    }
    private void refresh(int postId){
        DiscussPost post = discussPostService.findDiscussPostById(postId);
        //帖子有可能已经被置为删除状态
        if(post == null){
            logger.error("id为:"+postId+"的帖子不存在");
            return;
        }
        //是否加精
        boolean wonderful = post.getStatus() == 1;
        int commentCount = post.getCommentCount();
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST,postId);
        //计算权重
        double weight = (wonderful ? 75 : 0) + commentCount *  10 + likeCount * 2;
        // 分数 = 帖子权重 + 距离牛客纪元天数
        //Math.max(weight,1)是避免weight小于1时取对数为负数
        double score = Math.log10(Math.max(weight,1)) + (post.getCreateTime().getTime() - epoch.getTime()) / (1000 * 3600 * 24);
        discussPostService.updateScore(postId,score);
        //异步更新热帖缓存



        //同步es服务器上的数据
        elasticsearchService.saveDiscussPost(post);
    }
}
